package entjava.poker.service;

import entjava.poker.model.Card;

public class ComboService {

	private Card[] cards;
	private int highrankOnePair;
	private int highrankTwoPair;
	private int highrankThreeOfAKind;
	private int highrankFourOfAKind;
	private int highrankStright;
	
	public ComboService(Card[] cardList){	
		this.cards=cardList;	
	}

	//Royal Flush - An Ace-High straight of one suit.
	public boolean RoyalFlush(){
		System.out.println("In Royal flush");
	    if(Straight() == false && Flush() == false){		
	        return false;
	    }
	    
	    int[] values = new int[7];
        int pos;
        int temp;

        for(int i = 0; i < cards.length; i++){			//Set values in array
                values[i] = cards[i].getRankNum();
                
	                if(values[i] == 1)					//If Ace 
	                        values[i] = 14;
        }

        for(int i = 1; i < values.length; i++){			 //Sort Numerically
                pos = i;
                while(pos != 0){
                        if(values[pos] < values[pos-1]){
                                temp = values[pos];
                                values[pos] = values[pos-1];
                                values[pos-1]= temp;
                        }
                        pos--;
                }
        }

           if(values[0] == 10 || values[1]==10 || values[2]==10 ){			//Royal flush is a straight flush, with the lowest card being a 10	
      			return true;
           }else{
      		return false;
      		}	
	} 
	
	//Straight Flush - A straight of entirely one suit.
	public boolean StraightFlush(){
		
		if(Straight() == true && Flush() == true)						//If there's a straight and a flush present
			return true;

		return false;
	}
		
	
	//Four-of-a-Kind - Four cards of the same rank.
	public boolean FourOfAKind(){
		    String[] values = new String[7];
		    int counter = 0;

		    for(int i = 0; i < cards.length; i++){
		        values[i] = cards[i].getValue();
		    }

		    for(int x = 0; x < values.length; x++){								    //Same process as isPair(), except return true for 4 matches
		        for(int y = 0; y < cards.length; y++){
		            if(values[x].equals(cards[y].getValue()))
		                counter++;
		            if(counter == 4)
		                return true;
		        }
		        counter = 0;
		    }
		    return false;
		}

	 
	//Full House (Full Boat, Boat) - Three-of-a-kind and a pair. 
	public boolean FullHouse(){
		
		if(ThreeOfAKind()==true && OnePair()==true){
			return true;
		}else{
			return false;
		}
	} 
		
	
	//Flush - Five cards of the same suit.
	public boolean Flush(){
		String card = cards[0].getSuit();
	    int countSuit=0;
		for(int i = 1; i < cards.length; i++){
	        if((cards[i].getSuit().equals(card))){
	        	countSuit++;
	        }
	    }

		if(countSuit>=5){
			return true;
		}else{
			return false;
		}
	
	}
	    
	//Straight (Run) - Five cards of sequential rank. Note that in holdem, Aces can be high or low.
	public boolean Straight(){
		int[] values = new int[7];
		int pos;
		int temp;
		
		for(int i = 0; i < cards.length; i++){									//Set values in array
			values[i] = cards[i].getRankNum();
		}

		for(int i = 1; i < values.length; i++){									//Sort Numerically
			pos = i;
			while(pos != 0){
				if(values[pos] < values[pos-1]){
					temp = values[pos];
					values[pos] = values[pos-1];
					values[pos-1]= temp;
				}
				pos--;
			}
		}
		
		for(int i = 0; i < 5 - 1; i++){
			if(values[i] != values[i+1] - 1){
				return false;
			}
		}
		return true;
	}
		 
	
	//Three-of-a-Kind (Trips, Set, Triplets) - Three cards of the same rank.
	public boolean ThreeOfAKind(){
		 String[] values = new String[7];
		    int counter = 0;

		    for(int i = 0; i < cards.length; i++){
		        values[i] = cards[i].getValue();
		    }

		    for(int x = 0; x < values.length; x++){								    //Same process as isPair(), except return true for 3 matches
		        for(int y = 0; y < cards.length; y++){
		            if(values[x].equals(cards[y].getValue())){
		                counter++;
		                
		                highrankThreeOfAKind=cards[y].getRankNum();				//FOR TIE
		            }
		            if(counter == 3)
		                return true;
		        }
		        counter = 0;
		    }
		    return false;
	} 
	//Two Pair - Two cards of the same rank and another two cards of the same rank. 
	public boolean TwoPair(){
		    String[] values = new String[7];
		    int counter = 0;
		    int sum = 0;

		    if(FourOfAKind() == true)					    			//Two pairs can resemble 4 of a kind
		        return false;

		    for(int i = 0; i < cards.length; i++){					    //Insert Numeric values into array
		        values[i] = cards[i].getValue();
		    }

		    for(int x = 0; x < values.length; x++){
		        for(int y = 0; y < cards.length; y++){
		            if(values[x].equals(cards[y].getValue())){
		            counter++;
		            
		            highrankTwoPair=cards[y].getRankNum();				//FOR TIE
		            }
		        }
		    if(counter > 1)
		    sum++;
		    counter = 0;
		    }//end for

		    if(sum == 4)
		        return true;

		    return false;
	} 
	//One Pair - Two cards of the same rank.
	public boolean OnePair(){
		String[] values = new String[7];
	    int counter = 0;

	    for(int i = 0; i < cards.length; i++){							    //Put each cards rank value into array
	        values[i] = cards[i].getValue();
	    }

	    for(int x = 0; x < values.length; x++){								    //If exactly two matches are made - return true
	        for(int y = 0; y < cards.length; y++){
	            if(values[x].equals(cards[y].getValue())){
	            counter++;
	            
	            highrankOnePair=cards[y].getRankNum();				//FOR TIE
	            
	            }
	            if(counter == 2)
	            return true;
	        }
	        counter = 0;
	    }
	    return false;
	} 
	
	//High Card - When you don't have any of the above, your highest card determines your hand.
	public Card higherCard(){
		Card cardOne = cards[0];
		Card cardTwo = cards[1];
	
		Card highcard= null;
		
		if(cardOne.getRankNum()!=1){
			if(cardTwo.getRankNum()!=1){
				if(cardOne.getRankNum()>cardTwo.getRankNum()){
					highcard=cards[0];
				}else if(cardOne.getRankNum()<cardTwo.getRankNum()){
					highcard=cards[1];
				}else if(cardOne.getRankNum()==cardTwo.getRankNum()){
					//tie if the first one
					highcard=cards[0];
				}
			}else{
				highcard=cards[1];
			}
		}else{
			highcard=cards[0];
		}
		return highcard;
	}

	public int getHighrankOnePair() {
		return highrankOnePair;
	}

	public void setHighrankOnePair(int highrankOnePair) {
		this.highrankOnePair = highrankOnePair;
	}

	public int getHighrankTwoPair() {
		return highrankTwoPair;
	}

	public void setHighrankTwoPair(int highrankTwoPair) {
		this.highrankTwoPair = highrankTwoPair;
	}

	public int getHighrankThreeOfAKind() {
		return highrankThreeOfAKind;
	}

	public void setHighrankThreeOfAKind(int highrankThreeOfAKind) {
		this.highrankThreeOfAKind = highrankThreeOfAKind;
	}

	public int getHighrankFourOfAKind() {
		return highrankFourOfAKind;
	}

	public void setHighrankFourOfAKind(int highrankFourOfAKind) {
		this.highrankFourOfAKind = highrankFourOfAKind;
	}

	public int getHighrankStright() {
		return highrankStright;
	}

	public void setHighrankStright(int highrankStright) {
		this.highrankStright = highrankStright;
	}

}
